Demo: render_tabset()

Published

March 4, 2025

Basic usage

Here are basic examples. First, load the libraries used in this demo and create sample data.

library(quartabs)
library(tibble)
library(dplyr)
library(purrr)
library(tidyr)
library(knitr)
library(gt)
library(DT)
library(reactable)
library(flextable)
library(plotly)
library(leaflet)
library(htmltools)
library(janitor)
library(tinytable)

set.seed(123)

# sample data
df1 <- tibble(
  group1 = c(rep("A", 3), rep("B", 3)),
  group2 = rep(c("X", "Y", "Z"), 2),
  id = paste0("id", 1:6),
  var1 = rnorm(6),
  var2 = 1:6,
  var3 = factor(letters[1:6])
)

df1
# A tibble: 6 × 6
  group1 group2 id       var1  var2 var3 
  <chr>  <chr>  <chr>   <dbl> <int> <fct>
1 A      X      id1   -0.560      1 a    
2 A      Y      id2   -0.230      2 b    
3 A      Z      id3    1.56       3 c    
4 B      X      id4    0.0705     4 d    
5 B      Y      id5    0.129      5 e    
6 B      Z      id6    1.72       6 f    

results: asis

Don’t forget!

Write #| results: asis at the beginning of the chunk or results='asis' in the chunk options.

```{r}
#| results: asis

df1 |>
  render_tabset(id, var1)
```

-0.5604756

-0.2301775

1.558708

0.07050839

0.1292877

1.715065

This is equal to the following.

```{r, results='asis'}
df1 |>
  render_tabset(id, var1)
```

-0.5604756

-0.2301775

1.558708

0.07050839

0.1292877

1.715065

cat() or print()

Notice that the above output is not prefixed with “[1]” as in “[1] -0.5604756”. This is because cat() is used internally for non-list columns to avoid unnecessary prefixes such as “[1]” in the output. On the other hand, print() is used for list columns.

tabset_vars, output_vars

Multiple tabset_vars and output_vars are acceptable. For multiple tabset_vars, they are displayed nested.

df1 |>
  render_tabset(c(group1, group2), c(var1, var2, var3))

-0.5604756

1

a

-0.2301775

2

b

1.558708

3

c

0.07050839

4

d

0.1292877

5

e

1.715065

6

f

Characters or tidyselect can also be used for tabset_vars and output_vars.

vars <- c("var1", "var2", "var3")

df1 |>
  render_tabset(c("group1", "group2"), vars)

-0.5604756

1

a

-0.2301775

2

b

1.558708

3

c

0.07050839

4

d

0.1292877

5

e

1.715065

6

f

Factor output

In render_tabset(), cat() is used to output for columns that are not list types. However, if cat() is used, factor is output as an integer. So, if factor is included in output_vars, it is converted internally to string.

x <- factor("a")

# default factor output
print(x)
[1] a
Levels: a
# Using `cat()` for factor results in unexpected output
cat(x)
1
# `render_tabset()` converts factor to string
# and then executes cat() as follows.
cat(as.character(x))
a

layout

How can I display the content in a tabset horizontally? In quarto, layout-ncol can be used.

```{r}
#| results: asis
#| layout-ncol: 3

df1 |>
  render_tabset(c(group1, group2), c(var1, var2, var3))
```

-0.5604756

1

a

-0.2301775

2

b

1.558708

3

c

0.07050839

4

d

0.1292877

5

e

1.715065

6

f

Oops, the entire tabset is now a third of the width. We want the content within to be displayed side by side without changing the width of the tabset. This is where the layout argument comes in handy.

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    layout = "::: {layout-ncol=3}"
  )

-0.5604756

1

a

-0.2301775

2

b

1.558708

3

c

0.07050839

4

d

0.1292877

5

e

1.715065

6

f

For more information about layout, see Custom Layouts.

Warning
  • If you are viewing on a smartphone, the layout may not be displayed correctly.
  • The layout argument is intended for very simple use cases, so complex layouts may not work.

heading_levels

Use the heading_levels argument if you want the heading to be displayed as normal headings instead of tabsets. heading_levels and tabset_vars correspond in order. Each tabset_vars is expressed as the heading of specified in heading_levels. If the element of heading_levels is NA, then the element of its tabset_vars is represented as tabset.

Example 1

For example, group1 should be tabset and group2 should be h4 heading.

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    heading_levels = c(NA, 4)
  )

X

-0.5604756

1

a

Y

-0.2301775

2

b

Z

1.558708

3

c

X

0.07050839

4

d

Y

0.1292877

5

e

Z

1.715065

6

f

Example 2

Conversely, group1 should be heading 4 and group2 should be tabset.

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    heading_levels = c(4, NA)
  )

A

-0.5604756

1

a

-0.2301775

2

b

1.558708

3

c

B

0.07050839

4

d

0.1292877

5

e

1.715065

6

f

Example 3

Set group1 to heading 4 and group2 to heading 5 (no tabset).

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    heading_levels = c(4, 5)
  )

A

X

-0.5604756

1

a

Y

-0.2301775

2

b

Z

1.558708

3

c

B

X

0.07050839

4

d

Y

0.1292877

5

e

Z

1.715065

6

f

Example 4

Although it is preferable for the heading to be progressively larger due to the structure of the chapter, but can be the same or progressively smaller.

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    heading_levels = c(5, 4)
  )
A

X

-0.5604756

1

a

Y

-0.2301775

2

b

Z

1.558708

3

c

B

X

0.07050839

4

d

Y

0.1292877

5

e

Z

1.715065

6

f

Example 5

header_levels can work with layout.

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    layout = "::: {layout-ncol=3}",
    heading_levels = c(4, NA)
  )

A

-0.5604756

1

a

-0.2301775

2

b

1.558708

3

c

B

0.07050839

4

d

0.1292877

5

e

1.715065

6

f

pills

df1 |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    pills = TRUE
  )

tabset_width

df1_long_label <- df1 |> 
  mutate(
    group1 = paste("This is a long label for", group1)
  )

df1_long_label |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    tabset_width = "fill"
  )
df1_long_label |>
  render_tabset(
    c(group1, group2),
    c(var1, var2, var3),
    tabset_width = "justified"
  )

Figures and tables

This section shows more practical examples. Use the mtcars dataset, grouped by cyl and am, to create figures and tables showing the relationship between wt and mpg. render_tabset() was originally created to represent figures and tables as tabsets, with nested data frames as input. Nesting approach is useful when the same operation is performed on each group.

nest() + map()

We shows how to use tidyr::nest() and purrr::map() combination.

For more information on the nest, see follows:

# new sample data
df2 <- mtcars |>
  # make groups more explicit
  mutate(
    cyl = paste("cyl:", cyl),
    am = paste("am:", am)
  ) |>
  # nest
  nest(.by = c(cyl, am)) |>
  mutate(
    # create titles for figures
    title = paste(cyl, am, sep = ", "),
    # create scatter plots
    fig = map2(
      data,
      title,
      \(data, title) {
        data |>
          ggplot(aes(wt, mpg)) +
          geom_point() +
          labs(title = title)
      }
    ),
    # create tables
    tbl = map(
      data,
      \(data) {
        data |>
          select(wt, mpg) |>
          knitr::kable()
      }
    )
  )

df2
# A tibble: 6 × 6
  cyl    am    data              title         fig    tbl            
  <chr>  <chr> <list>            <chr>         <list> <list>         
1 cyl: 6 am: 1 <tibble [3 × 9]>  cyl: 6, am: 1 <gg>   <kntr_kbl [5]> 
2 cyl: 4 am: 1 <tibble [8 × 9]>  cyl: 4, am: 1 <gg>   <kntr_kbl [10]>
3 cyl: 6 am: 0 <tibble [4 × 9]>  cyl: 6, am: 0 <gg>   <kntr_kbl [6]> 
4 cyl: 8 am: 0 <tibble [12 × 9]> cyl: 8, am: 0 <gg>   <kntr_kbl [14]>
5 cyl: 4 am: 0 <tibble [3 × 9]>  cyl: 4, am: 0 <gg>   <kntr_kbl [5]> 
6 cyl: 8 am: 1 <tibble [2 × 9]>  cyl: 8, am: 1 <gg>   <kntr_kbl [4]> 

Figures and tables have been created for the fig and tbl columns respectively. Also note that the group variables cly and am are not ordered in regular ascending order. They are arranged in order of appearance. In Next step, specifying cly and am in tabset_vars in render_tabset() automatically executes arrange(cly, am) internally. So don’t worry.

Tip

We did not run arrange(cly, am) in this example for the sake of example, but in practice it is better to run arrange(cly, am) in the pipeline to make it easier to identify each group.

df2 |>
  arrange(cyl, am)
# A tibble: 6 × 6
  cyl    am    data              title         fig    tbl            
  <chr>  <chr> <list>            <chr>         <list> <list>         
1 cyl: 4 am: 0 <tibble [3 × 9]>  cyl: 4, am: 0 <gg>   <kntr_kbl [5]> 
2 cyl: 4 am: 1 <tibble [8 × 9]>  cyl: 4, am: 1 <gg>   <kntr_kbl [10]>
3 cyl: 6 am: 0 <tibble [4 × 9]>  cyl: 6, am: 0 <gg>   <kntr_kbl [6]> 
4 cyl: 6 am: 1 <tibble [3 × 9]>  cyl: 6, am: 1 <gg>   <kntr_kbl [5]> 
5 cyl: 8 am: 0 <tibble [12 × 9]> cyl: 8, am: 0 <gg>   <kntr_kbl [14]>
6 cyl: 8 am: 1 <tibble [2 × 9]>  cyl: 8, am: 1 <gg>   <kntr_kbl [4]> 

nest_by() + list()

Another method is to use dplyr::nest_by() and list(). This approach is simpler and more intuitive to write.

For more information, see follows:

df2_rowwise <- mtcars |>
  # make groups more explicit
  mutate(
    cyl = paste("cyl:", cyl),
    am = paste("am:", am)
  ) |>
  # nest
  nest_by(cyl, am) |>
  mutate(
    # create titles for figures
    title = paste(cyl, am, sep = ", "),
    # create scatter plots
    fig = list(
      data |>
        ggplot(aes(wt, mpg)) +
        geom_point() +
        labs(title = title)
    ),
    # create tables
    tbl = list(
      data |>
        select(wt, mpg) |>
        knitr::kable()
    )
  )

df2_rowwise
# A tibble: 6 × 6
# Rowwise:  cyl, am
  cyl    am                  data title         fig    tbl            
  <chr>  <chr> <list<tibble[,9]>> <chr>         <list> <list>         
1 cyl: 4 am: 0            [3 × 9] cyl: 4, am: 0 <gg>   <kntr_kbl [5]> 
2 cyl: 4 am: 1            [8 × 9] cyl: 4, am: 1 <gg>   <kntr_kbl [10]>
3 cyl: 6 am: 0            [4 × 9] cyl: 6, am: 0 <gg>   <kntr_kbl [6]> 
4 cyl: 6 am: 1            [3 × 9] cyl: 6, am: 1 <gg>   <kntr_kbl [5]> 
5 cyl: 8 am: 0           [12 × 9] cyl: 8, am: 0 <gg>   <kntr_kbl [14]>
6 cyl: 8 am: 1            [2 × 9] cyl: 8, am: 1 <gg>   <kntr_kbl [4]> 

This way, the values of other columns in the list() can be used freely. (In the nest() + map() method, it was necessary to define in advance which columns to use when calling in the map()).

The outputs are grouped rowwise and already sorted by cly and am.

Figures

In the following, df2 is used. (Works in the same way in df2_rowwise).

df2 |>
  render_tabset(c(cyl, am), fig)

Tables

df2 |>
  render_tabset(c(cyl, am), tbl)
wt mpg
3.190 24.4
3.150 22.8
2.465 21.5
wt mpg
2.320 22.8
2.200 32.4
1.615 30.4
1.835 33.9
1.935 27.3
2.140 26.0
1.513 30.4
2.780 21.4
wt mpg
3.215 21.4
3.460 18.1
3.440 19.2
3.440 17.8
wt mpg
2.620 21.0
2.875 21.0
2.770 19.7
wt mpg
3.440 18.7
3.570 14.3
4.070 16.4
3.730 17.3
3.780 15.2
5.250 10.4
5.424 10.4
5.345 14.7
3.520 15.5
3.435 15.2
3.840 13.3
3.845 19.2
wt mpg
3.17 15.8
3.57 15.0

Figures and tables

df2 |>
  render_tabset(c(cyl, am), c(fig, tbl))

wt mpg
3.190 24.4
3.150 22.8
2.465 21.5

wt mpg
2.320 22.8
2.200 32.4
1.615 30.4
1.835 33.9
1.935 27.3
2.140 26.0
1.513 30.4
2.780 21.4

wt mpg
3.215 21.4
3.460 18.1
3.440 19.2
3.440 17.8

wt mpg
2.620 21.0
2.875 21.0
2.770 19.7

wt mpg
3.440 18.7
3.570 14.3
4.070 16.4
3.730 17.3
3.780 15.2
5.250 10.4
5.424 10.4
5.345 14.7
3.520 15.5
3.435 15.2
3.840 13.3
3.845 19.2

wt mpg
3.17 15.8
3.57 15.0

layout

Use the layout argument to display figure and table side by side with a width of 7:3.

df2 |>
  render_tabset(c(cyl, am), c(fig, tbl), layout = '::: {layout="[7, 3]"}')

wt mpg
3.190 24.4
3.150 22.8
2.465 21.5

wt mpg
2.320 22.8
2.200 32.4
1.615 30.4
1.835 33.9
1.935 27.3
2.140 26.0
1.513 30.4
2.780 21.4

wt mpg
3.215 21.4
3.460 18.1
3.440 19.2
3.440 17.8

wt mpg
2.620 21.0
2.875 21.0
2.770 19.7

wt mpg
3.440 18.7
3.570 14.3
4.070 16.4
3.730 17.3
3.780 15.2
5.250 10.4
5.424 10.4
5.345 14.7
3.520 15.5
3.435 15.2
3.840 13.3
3.845 19.2

wt mpg
3.17 15.8
3.57 15.0

Advanced examples

Pre-saved figures

Plotly

You can use {plotly} to create interactive figures.

First, let’s create figures using {plotly}. Simply apply plotly::ggplotly() to the already created ggplot object. Then it is passed to htmltools::div().

df4 <- df2 |>
  mutate(
    fig_plotly = map(
      fig,
      \(p) {
        ggplotly(
          p,
          height = 700 # make large figure, for example
        ) |>
          htmltools::div()
      }
    )
  ) |>
  select(cyl, am, fig_plotly)

df4
# A tibble: 6 × 3
  cyl    am    fig_plotly
  <chr>  <chr> <list>    
1 cyl: 6 am: 1 <shiny.tg>
2 cyl: 4 am: 1 <shiny.tg>
3 cyl: 6 am: 0 <shiny.tg>
4 cyl: 8 am: 0 <shiny.tg>
5 cyl: 4 am: 0 <shiny.tg>
6 cyl: 8 am: 1 <shiny.tg>
Resolve javascript dependencies

When outputting tables or figures that use javascript (such as {plotly}, {leaflet}, {DT}, {reactable}, etc.), it seems javascript dependencies need to be resolved. The easiest way seems to output them once in a separate chunk.

References:

As above, this example prepares a chunk that executes only plot_ly(). Set #| include: false so that this chunk and its output will not appear on the report.

```{r}
#| include: false

plot_ly()
```

Then execute render_tabset() as in basic usage. Add column: page-right chunk option to increase the size of the figure.

```{r}
#| results: asis
#| column: page-right

df4 |>
  render_tabset(c(cyl, am), fig_plotly)
```

Leaflet

Tables

Here we will show you how to use render_tabset() in a popular package for rendering tables. This example uses knitr::kable(), gt::gt(), gt::opt_interactive(), flextable::flextable(), DT::datatable(), reactable::reactable() and tinytable::tt().

tables <-
  df2 |>
  select(cyl, am, data) |>
  mutate(
    kable = map(data, knitr::kable),
    gt = map(data, gt::gt),
    gt_interactive = map(gt, gt::opt_interactive),
    tt = map(data, tinytable::tt),
    flex = map_chr(
      data,
      \(data) {
        flextable::flextable(data) |>
          knitr::knit_print()
      }
    ),
    DT = map(
      data,
      \(data) {
        DT::datatable(data) |>
          htmltools::div()
      }
    ),
    reac = map(
      data,
      \(data) {
        reactable::reactable(data) |>
          htmltools::div()
      }
    ),
    section_kable = "#### knitr::kable()",
    section_gt = "#### gt::gt()",
    section_gt_interactive = paste(
      "#### gt::gt() |> gt::opt_interactive()",
      "(and run in a separate chunk)"
    ),
    section_tt = "#### tinytable::tt()",
    section_flex = paste(
      "#### flextable::flextable() |> knitr::knit_print()",
      "(using map_chr())"
    ),
    section_DT = paste(
      "#### DT::datatable() |> htmltools::div()",
      "(and run in a separate chunk)"
    ),
    section_reac = paste(
      "#### reactable::reactable() |> htmltools::div()",
      "(and run in a separate chunk)"
    )
  )

tables
# A tibble: 6 × 17
  cyl    am    data     kable      gt       gt_interactive tt             flex  
  <chr>  <chr> <list>   <list>     <list>   <list>         <list>         <chr> 
1 cyl: 6 am: 1 <tibble> <kntr_kbl> <gt_tbl> <gt_tbl [17]>  <tinytabl[,9]> "\n``…
2 cyl: 4 am: 1 <tibble> <kntr_kbl> <gt_tbl> <gt_tbl [17]>  <tinytabl[,9]> "\n``…
3 cyl: 6 am: 0 <tibble> <kntr_kbl> <gt_tbl> <gt_tbl [17]>  <tinytabl[,9]> "\n``…
4 cyl: 8 am: 0 <tibble> <kntr_kbl> <gt_tbl> <gt_tbl [17]>  <tinytabl[,9]> "\n``…
5 cyl: 4 am: 0 <tibble> <kntr_kbl> <gt_tbl> <gt_tbl [17]>  <tinytabl[,9]> "\n``…
6 cyl: 8 am: 1 <tibble> <kntr_kbl> <gt_tbl> <gt_tbl [17]>  <tinytabl[,9]> "\n``…
# ℹ 9 more variables: DT <list>, reac <list>, section_kable <chr>,
#   section_gt <chr>, section_gt_interactive <chr>, section_tt <chr>,
#   section_flex <chr>, section_DT <chr>, section_reac <chr>

knitr::kable(), gt::gt(), and tinytable::tt() are the simplest.

The output of flextable::flextable() is managed by the method knitr::knit_print(). After execution, raw HTML is obtained, which is turned into a character type column using map_chr().

gt::opt_interactive(), {DT} and {reactable} use javascript. They should be wrapped with htmltools::div(), except for gt::opt_interactive(), and run in a separate chunk to resolve javascript dependencies. Don’t forget #| include: false.

```{r}
#| include: false

gt::gt(mtcars) |>
  gt::opt_interactive()

DT::datatable(mtcars)

reactable::reactable(mtcars)
```

Then execute render_tabset(). To make the results easier to see, sections are also to be added.

tables |>
  render_tabset(
    c(cyl, am),
    c(
      section_kable,
      kable,
      section_gt,
      gt,
      section_gt_interactive,
      gt_interactive,
      section_tt,
      tt,
      section_flex,
      flex,
      section_DT,
      DT,
      section_reac,
      reac
    )
  )

knitr::kable()

mpg disp hp drat wt qsec vs gear carb
24.4 146.7 62 3.69 3.190 20.00 1 4 2
22.8 140.8 95 3.92 3.150 22.90 1 4 2
21.5 120.1 97 3.70 2.465 20.01 1 3 1

gt::gt()

mpg disp hp drat wt qsec vs gear carb
24.4 146.7 62 3.69 3.190 20.00 1 4 2
22.8 140.8 95 3.92 3.150 22.90 1 4 2
21.5 120.1 97 3.70 2.465 20.01 1 3 1

gt::gt() |> gt::opt_interactive() (and run in a separate chunk)

tinytable::tt()

mpg disp hp drat wt qsec vs gear carb
24.4 146.7 62 3.69 3.190 20.00 1 4 2
22.8 140.8 95 3.92 3.150 22.90 1 4 2
21.5 120.1 97 3.70 2.465 20.01 1 3 1

flextable::flextable() |> knitr::knit_print() (using map_chr())

mpg

disp

hp

drat

wt

qsec

vs

gear

carb

24.4

146.7

62

3.69

3.190

20.00

1

4

2

22.8

140.8

95

3.92

3.150

22.90

1

4

2

21.5

120.1

97

3.70

2.465

20.01

1

3

1

DT::datatable() |> htmltools::div() (and run in a separate chunk)

reactable::reactable() |> htmltools::div() (and run in a separate chunk)

knitr::kable()

mpg disp hp drat wt qsec vs gear carb
22.8 108.0 93 3.85 2.320 18.61 1 4 1
32.4 78.7 66 4.08 2.200 19.47 1 4 1
30.4 75.7 52 4.93 1.615 18.52 1 4 2
33.9 71.1 65 4.22 1.835 19.90 1 4 1
27.3 79.0 66 4.08 1.935 18.90 1 4 1
26.0 120.3 91 4.43 2.140 16.70 0 5 2
30.4 95.1 113 3.77 1.513 16.90 1 5 2
21.4 121.0 109 4.11 2.780 18.60 1 4 2

gt::gt()

mpg disp hp drat wt qsec vs gear carb
22.8 108.0 93 3.85 2.320 18.61 1 4 1
32.4 78.7 66 4.08 2.200 19.47 1 4 1
30.4 75.7 52 4.93 1.615 18.52 1 4 2
33.9 71.1 65 4.22 1.835 19.90 1 4 1
27.3 79.0 66 4.08 1.935 18.90 1 4 1
26.0 120.3 91 4.43 2.140 16.70 0 5 2
30.4 95.1 113 3.77 1.513 16.90 1 5 2
21.4 121.0 109 4.11 2.780 18.60 1 4 2

gt::gt() |> gt::opt_interactive() (and run in a separate chunk)

tinytable::tt()

mpg disp hp drat wt qsec vs gear carb
22.8 108.0 93 3.85 2.320 18.61 1 4 1
32.4 78.7 66 4.08 2.200 19.47 1 4 1
30.4 75.7 52 4.93 1.615 18.52 1 4 2
33.9 71.1 65 4.22 1.835 19.90 1 4 1
27.3 79.0 66 4.08 1.935 18.90 1 4 1
26.0 120.3 91 4.43 2.140 16.70 0 5 2
30.4 95.1 113 3.77 1.513 16.90 1 5 2
21.4 121.0 109 4.11 2.780 18.60 1 4 2

flextable::flextable() |> knitr::knit_print() (using map_chr())

mpg

disp

hp

drat

wt

qsec

vs

gear

carb

22.8

108.0

93

3.85

2.320

18.61

1

4

1

32.4

78.7

66

4.08

2.200

19.47

1

4

1

30.4

75.7

52

4.93

1.615

18.52

1

4

2

33.9

71.1

65

4.22

1.835

19.90

1

4

1

27.3

79.0

66

4.08

1.935

18.90

1

4

1

26.0

120.3

91

4.43

2.140

16.70

0

5

2

30.4

95.1

113

3.77

1.513

16.90

1

5

2

21.4

121.0

109

4.11

2.780

18.60

1

4

2

DT::datatable() |> htmltools::div() (and run in a separate chunk)

reactable::reactable() |> htmltools::div() (and run in a separate chunk)

knitr::kable()

mpg disp hp drat wt qsec vs gear carb
21.4 258.0 110 3.08 3.215 19.44 1 3 1
18.1 225.0 105 2.76 3.460 20.22 1 3 1
19.2 167.6 123 3.92 3.440 18.30 1 4 4
17.8 167.6 123 3.92 3.440 18.90 1 4 4

gt::gt()

mpg disp hp drat wt qsec vs gear carb
21.4 258.0 110 3.08 3.215 19.44 1 3 1
18.1 225.0 105 2.76 3.460 20.22 1 3 1
19.2 167.6 123 3.92 3.440 18.30 1 4 4
17.8 167.6 123 3.92 3.440 18.90 1 4 4

gt::gt() |> gt::opt_interactive() (and run in a separate chunk)

tinytable::tt()

mpg disp hp drat wt qsec vs gear carb
21.4 258.0 110 3.08 3.215 19.44 1 3 1
18.1 225.0 105 2.76 3.460 20.22 1 3 1
19.2 167.6 123 3.92 3.440 18.30 1 4 4
17.8 167.6 123 3.92 3.440 18.90 1 4 4

flextable::flextable() |> knitr::knit_print() (using map_chr())

mpg

disp

hp

drat

wt

qsec

vs

gear

carb

21.4

258.0

110

3.08

3.215

19.44

1

3

1

18.1

225.0

105

2.76

3.460

20.22

1

3

1

19.2

167.6

123

3.92

3.440

18.30

1

4

4

17.8

167.6

123

3.92

3.440

18.90

1

4

4

DT::datatable() |> htmltools::div() (and run in a separate chunk)

reactable::reactable() |> htmltools::div() (and run in a separate chunk)

knitr::kable()

mpg disp hp drat wt qsec vs gear carb
21.0 160 110 3.90 2.620 16.46 0 4 4
21.0 160 110 3.90 2.875 17.02 0 4 4
19.7 145 175 3.62 2.770 15.50 0 5 6

gt::gt()

mpg disp hp drat wt qsec vs gear carb
21.0 160 110 3.90 2.620 16.46 0 4 4
21.0 160 110 3.90 2.875 17.02 0 4 4
19.7 145 175 3.62 2.770 15.50 0 5 6

gt::gt() |> gt::opt_interactive() (and run in a separate chunk)

tinytable::tt()

mpg disp hp drat wt qsec vs gear carb
21.0 160 110 3.90 2.620 16.46 0 4 4
21.0 160 110 3.90 2.875 17.02 0 4 4
19.7 145 175 3.62 2.770 15.50 0 5 6

flextable::flextable() |> knitr::knit_print() (using map_chr())

mpg

disp

hp

drat

wt

qsec

vs

gear

carb

21.0

160

110

3.90

2.620

16.46

0

4

4

21.0

160

110

3.90

2.875

17.02

0

4

4

19.7

145

175

3.62

2.770

15.50

0

5

6

DT::datatable() |> htmltools::div() (and run in a separate chunk)

reactable::reactable() |> htmltools::div() (and run in a separate chunk)

knitr::kable()

mpg disp hp drat wt qsec vs gear carb
18.7 360.0 175 3.15 3.440 17.02 0 3 2
14.3 360.0 245 3.21 3.570 15.84 0 3 4
16.4 275.8 180 3.07 4.070 17.40 0 3 3
17.3 275.8 180 3.07 3.730 17.60 0 3 3
15.2 275.8 180 3.07 3.780 18.00 0 3 3
10.4 472.0 205 2.93 5.250 17.98 0 3 4
10.4 460.0 215 3.00 5.424 17.82 0 3 4
14.7 440.0 230 3.23 5.345 17.42 0 3 4
15.5 318.0 150 2.76 3.520 16.87 0 3 2
15.2 304.0 150 3.15 3.435 17.30 0 3 2
13.3 350.0 245 3.73 3.840 15.41 0 3 4
19.2 400.0 175 3.08 3.845 17.05 0 3 2

gt::gt()

mpg disp hp drat wt qsec vs gear carb
18.7 360.0 175 3.15 3.440 17.02 0 3 2
14.3 360.0 245 3.21 3.570 15.84 0 3 4
16.4 275.8 180 3.07 4.070 17.40 0 3 3
17.3 275.8 180 3.07 3.730 17.60 0 3 3
15.2 275.8 180 3.07 3.780 18.00 0 3 3
10.4 472.0 205 2.93 5.250 17.98 0 3 4
10.4 460.0 215 3.00 5.424 17.82 0 3 4
14.7 440.0 230 3.23 5.345 17.42 0 3 4
15.5 318.0 150 2.76 3.520 16.87 0 3 2
15.2 304.0 150 3.15 3.435 17.30 0 3 2
13.3 350.0 245 3.73 3.840 15.41 0 3 4
19.2 400.0 175 3.08 3.845 17.05 0 3 2

gt::gt() |> gt::opt_interactive() (and run in a separate chunk)

tinytable::tt()

mpg disp hp drat wt qsec vs gear carb
18.7 360.0 175 3.15 3.440 17.02 0 3 2
14.3 360.0 245 3.21 3.570 15.84 0 3 4
16.4 275.8 180 3.07 4.070 17.40 0 3 3
17.3 275.8 180 3.07 3.730 17.60 0 3 3
15.2 275.8 180 3.07 3.780 18.00 0 3 3
10.4 472.0 205 2.93 5.250 17.98 0 3 4
10.4 460.0 215 3.00 5.424 17.82 0 3 4
14.7 440.0 230 3.23 5.345 17.42 0 3 4
15.5 318.0 150 2.76 3.520 16.87 0 3 2
15.2 304.0 150 3.15 3.435 17.30 0 3 2
13.3 350.0 245 3.73 3.840 15.41 0 3 4
19.2 400.0 175 3.08 3.845 17.05 0 3 2

flextable::flextable() |> knitr::knit_print() (using map_chr())

mpg

disp

hp

drat

wt

qsec

vs

gear

carb

18.7

360.0

175

3.15

3.440

17.02

0

3

2

14.3

360.0

245

3.21

3.570

15.84

0

3

4

16.4

275.8

180

3.07

4.070

17.40

0

3

3

17.3

275.8

180

3.07

3.730

17.60

0

3

3

15.2

275.8

180

3.07

3.780

18.00

0

3

3

10.4

472.0

205

2.93

5.250

17.98

0

3

4

10.4

460.0

215

3.00

5.424

17.82

0

3

4

14.7

440.0

230

3.23

5.345

17.42

0

3

4

15.5

318.0

150

2.76

3.520

16.87

0

3

2

15.2

304.0

150

3.15

3.435

17.30

0

3

2

13.3

350.0

245

3.73

3.840

15.41

0

3

4

19.2

400.0

175

3.08

3.845

17.05

0

3

2

DT::datatable() |> htmltools::div() (and run in a separate chunk)

reactable::reactable() |> htmltools::div() (and run in a separate chunk)

knitr::kable()

mpg disp hp drat wt qsec vs gear carb
15.8 351 264 4.22 3.17 14.5 0 5 4
15.0 301 335 3.54 3.57 14.6 0 5 8

gt::gt()

mpg disp hp drat wt qsec vs gear carb
15.8 351 264 4.22 3.17 14.5 0 5 4
15.0 301 335 3.54 3.57 14.6 0 5 8

gt::gt() |> gt::opt_interactive() (and run in a separate chunk)

tinytable::tt()

mpg disp hp drat wt qsec vs gear carb
15.8 351 264 4.22 3.17 14.5 0 5 4
15.0 301 335 3.54 3.57 14.6 0 5 8

flextable::flextable() |> knitr::knit_print() (using map_chr())

mpg

disp

hp

drat

wt

qsec

vs

gear

carb

15.8

351

264

4.22

3.17

14.5

0

5

4

15.0

301

335

3.54

3.57

14.6

0

5

8

DT::datatable() |> htmltools::div() (and run in a separate chunk)

reactable::reactable() |> htmltools::div() (and run in a separate chunk)

Session Info
# save the session info as an object
sess <- sessioninfo::session_info(pkgs = "attached")

# inject the quarto info
sess$platform$quarto <- paste(
  quarto::quarto_version(),
  "@",
  fs::path_real(quarto::quarto_path())
)

# print it out
sess
─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.4.3 (2025-02-28)
 os       Ubuntu 24.04.2 LTS
 system   x86_64, linux-gnu
 ui       X11
 language (EN)
 collate  C.UTF-8
 ctype    C.UTF-8
 tz       Etc/UTC
 date     2025-03-04
 pandoc   3.4 @ /opt/quarto/bin/tools/ (via rmarkdown)
 quarto   1.6.42 @ /opt/quarto/bin/quarto

─ Packages ───────────────────────────────────────────────────────────────────
 package   * version    date (UTC) lib source
 dplyr     * 1.1.4      2023-11-17 [2] RSPM (R 4.4.0)
 DT        * 0.33       2024-04-04 [2] RSPM (R 4.4.0)
 flextable * 0.9.7      2024-10-27 [2] RSPM (R 4.4.0)
 ggplot2   * 3.5.1      2024-04-23 [2] RSPM (R 4.4.0)
 gt        * 0.11.1     2024-10-04 [2] RSPM (R 4.4.0)
 htmltools * 0.5.8.1    2024-04-04 [2] RSPM (R 4.4.0)
 janitor   * 2.2.1      2024-12-22 [2] RSPM (R 4.4.0)
 knitr     * 1.49       2024-11-08 [2] RSPM (R 4.4.0)
 leaflet   * 2.2.2      2024-03-26 [2] RSPM (R 4.4.0)
 plotly    * 4.10.4     2024-01-13 [2] RSPM (R 4.4.0)
 purrr     * 1.0.4      2025-02-05 [2] RSPM (R 4.4.0)
 quartabs  * 0.0.0.9000 2025-03-04 [1] local
 reactable * 0.4.4      2023-03-12 [2] RSPM (R 4.4.0)
 tibble    * 3.2.1      2023-03-20 [2] RSPM (R 4.4.2)
 tidyr     * 1.3.1      2024-01-24 [2] RSPM (R 4.4.0)
 tinytable * 0.7.0      2025-01-24 [2] RSPM (R 4.4.0)

 [1] /usr/local/lib/R/site-library
 [2] /usr/lib/R/site-library
 [3] /usr/lib/R/library
 * ── Packages attached to the search path.

──────────────────────────────────────────────────────────────────────────────